"""阿里云盘上传操作模块

实现阿里云盘的文件上传、秒传等功能。
"""

import os
import hashlib
import json
from typing import Dict, Any, Optional, List
import requests
from ..base_client import BaseCloudClient


class UploadOperations:
    """阿里云盘上传操作类"""
    
    def __init__(self, client: BaseCloudClient):
        self.client = client
        self.session = client.session
    
    def check_fast_upload(self, file_path: str, parent_file_id: str = "root") -> Dict[str, Any]:
        """检查文件是否可以秒传
        
        Args:
            file_path: 本地文件路径
            parent_file_id: 父文件夹ID，默认为根目录
            
        Returns:
            检查结果，包含是否可以秒传的信息
        """
        try:
            if not os.path.exists(file_path):
                return {"success": False, "error": "文件不存在"}
            
            file_size = os.path.getsize(file_path)
            file_name = os.path.basename(file_path)
            
            # 计算文件哈希
            content_hash = self._calculate_content_hash(file_path)
            
            # 调用阿里云盘API检查秒传
            url = "https://api.aliyundrive.com/v2/file/create"
            headers = {
                "Authorization": f"Bearer {self.client.access_token}",
                "Content-Type": "application/json"
            }
            
            data = {
                "drive_id": self.client.drive_id,
                "parent_file_id": parent_file_id,
                "name": file_name,
                "type": "file",
                "size": file_size,
                "content_hash": content_hash,
                "content_hash_name": "sha1",
                "check_name_mode": "auto_rename"
            }
            
            response = self.session.post(url, headers=headers, json=data)
            
            if response.status_code == 201:
                result = response.json()
                if result.get("rapid_upload"):
                    return {
                        "success": True,
                        "can_fast_upload": True,
                        "file_id": result.get("file_id"),
                        "upload_id": result.get("upload_id")
                    }
                else:
                    return {
                        "success": True,
                        "can_fast_upload": False,
                        "upload_id": result.get("upload_id"),
                        "part_info_list": result.get("part_info_list", [])
                    }
            else:
                return {"success": False, "error": f"检查秒传失败: {response.text}"}
                
        except Exception as e:
            return {"success": False, "error": f"检查秒传异常: {str(e)}"}
    
    def fast_upload(self, file_path: str, parent_file_id: str = "root") -> Dict[str, Any]:
        """执行文件秒传
        
        Args:
            file_path: 本地文件路径
            parent_file_id: 父文件夹ID，默认为根目录
            
        Returns:
            秒传结果
        """
        try:
            # 先检查是否可以秒传
            check_result = self.check_fast_upload(file_path, parent_file_id)
            
            if not check_result["success"]:
                return check_result
            
            if check_result["can_fast_upload"]:
                return {
                    "success": True,
                    "message": "文件秒传成功",
                    "file_id": check_result["file_id"]
                }
            else:
                return {
                    "success": False,
                    "error": "文件不支持秒传，需要普通上传",
                    "upload_info": check_result
                }
                
        except Exception as e:
            return {"success": False, "error": f"秒传异常: {str(e)}"}
    
    def upload_file(self, file_path: str, remote_path: str = "/", parent_file_id: str = "root") -> Dict[str, Any]:
        """上传文件
        
        Args:
            file_path: 本地文件路径
            remote_path: 远程路径（暂时未使用）
            parent_file_id: 父文件夹ID，默认为根目录
            
        Returns:
            上传结果
        """
        try:
            if not os.path.exists(file_path):
                return {"success": False, "error": "文件不存在"}
            
            # 先尝试秒传
            fast_result = self.fast_upload(file_path, parent_file_id)
            if fast_result["success"]:
                return fast_result
            
            # 秒传失败，执行普通上传
            if "upload_info" in fast_result:
                upload_info = fast_result["upload_info"]
                return self._normal_upload(file_path, upload_info)
            else:
                return {"success": False, "error": "获取上传信息失败"}
                
        except Exception as e:
            return {"success": False, "error": f"上传文件异常: {str(e)}"}
    
    def _normal_upload(self, file_path: str, upload_info: Dict[str, Any]) -> Dict[str, Any]:
        """执行普通上传
        
        Args:
            file_path: 本地文件路径
            upload_info: 上传信息
            
        Returns:
            上传结果
        """
        try:
            upload_id = upload_info.get("upload_id")
            part_info_list = upload_info.get("part_info_list", [])
            
            if not upload_id or not part_info_list:
                return {"success": False, "error": "上传信息不完整"}
            
            file_size = os.path.getsize(file_path)
            
            # 分片上传
            with open(file_path, 'rb') as f:
                for part_info in part_info_list:
                    part_number = part_info["part_number"]
                    upload_url = part_info["upload_url"]
                    
                    # 计算分片范围
                    start = (part_number - 1) * 10 * 1024 * 1024  # 10MB per part
                    end = min(start + 10 * 1024 * 1024, file_size)
                    
                    f.seek(start)
                    chunk_data = f.read(end - start)
                    
                    # 上传分片
                    response = self.session.put(upload_url, data=chunk_data)
                    if response.status_code != 200:
                        return {"success": False, "error": f"分片{part_number}上传失败"}
            
            # 完成上传
            return self._complete_upload(upload_id)
            
        except Exception as e:
            return {"success": False, "error": f"普通上传异常: {str(e)}"}
    
    def _complete_upload(self, upload_id: str) -> Dict[str, Any]:
        """完成上传
        
        Args:
            upload_id: 上传ID
            
        Returns:
            完成结果
        """
        try:
            url = "https://api.aliyundrive.com/v2/file/complete"
            headers = {
                "Authorization": f"Bearer {self.client.access_token}",
                "Content-Type": "application/json"
            }
            
            data = {
                "drive_id": self.client.drive_id,
                "upload_id": upload_id
            }
            
            response = self.session.post(url, headers=headers, json=data)
            
            if response.status_code == 200:
                result = response.json()
                return {
                    "success": True,
                    "message": "文件上传成功",
                    "file_id": result.get("file_id")
                }
            else:
                return {"success": False, "error": f"完成上传失败: {response.text}"}
                
        except Exception as e:
            return {"success": False, "error": f"完成上传异常: {str(e)}"}
    
    def _calculate_content_hash(self, file_path: str) -> str:
        """计算文件内容哈希（SHA1）
        
        Args:
            file_path: 文件路径
            
        Returns:
            文件的SHA1哈希值
        """
        sha1_hash = hashlib.sha1()
        with open(file_path, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), b""):
                sha1_hash.update(chunk)
        return sha1_hash.hexdigest().upper()